package services

import (
	"fmt"
	"github.com/beego/beego/v2/client/orm"
	"github.com/pkg/errors"
	"time"
	"weiboxs.com/new_h_glasses/models"
	"weiboxs.com/new_h_glasses/utils"
)

type BadreportService struct {
}

func (s *BadreportService) CreateEntryNumber() string {
	stat := utils.GetDateParse(time.Now().Format("2006-01-02"))
	end := stat + 86400
	return fmt.Sprintf("%s%06d", time.Now().Format("20060102150405"), models.QueryBadreportTimeSoltSeterCount(stat, end, )+1)
}

//生成报损单
func (s *BadreportService) CreateBadreport(badreport *models.ErpBadreport) (int64, error) {

	badreport.Number = s.CreateEntryNumber()

	//清除原有临时数据
	isTemp := new(models.ErpBadreport)
	orm.NewOrm().QueryTable(models.ErpBadreportTableName()).Filter("DepartmentId", badreport.DepartmentId).Filter("is_temp", 1).Filter("BadreportUser", badreport.BadreportUser).One(isTemp)
	if isTemp.Id > 0 { //大于0表示有临时数据
		if _, err := orm.NewOrm().Delete(isTemp); err != nil {
			return 0, err
		}
		//删除明细信息
		if _, err := orm.NewOrm().Raw("DELETE FROM "+models.ErpBadreportDataTableName()+" WHERE badreport_id=?", isTemp.Id).Exec(); err != nil {
			return 0, err
		}
	}
	//写入新的数据
	if _, err := orm.NewOrm().Insert(badreport); err != nil {
		return 0, err
	}

	return badreport.Id, nil
}

//添加报损明细
func (s *BadreportService) AddBadreportData(entry_id, inv_id, badreport_num int64, badreport_reson string) error {
	if entry_id == 0 || inv_id == 0 {
		return errors.New("参数错误")
	}
	data := new(models.ErpBadreportData)
	data.Inventory = &models.ErpInventory{Id: inv_id}
	data.Badreport = &models.ErpBadreport{Id: entry_id}
	data.BadreportNum = badreport_num
	data.BadreportReson = badreport_reson

	if _, err := orm.NewOrm().Insert(data); err != nil {
		return err
	}

	return nil
}

//删除报损明细
func (s *BadreportService) DeleteBadreportData(entry_id, data_id int64) error {

	data := new(models.ErpBadreportData)
	data.Id = data_id

	if err := orm.NewOrm().Read(data); err != nil {
		return err
	}
	if data.Badreport.Id != entry_id {
		return errors.New("删除出错")
	}

	if _, err := orm.NewOrm().Delete(data); err != nil {
		return nil
	}

	return nil
}

//删除报损单
func (s *BadreportService) DeleteBadreport(depid, id int64) error {
	badreport := new(models.ErpBadreport)
	badreport.Id = id
	to,_ := orm.NewOrm().Begin()
	err := to.Read(badreport)
	if err != nil {
		return err
	}
	if badreport.DepartmentId != depid {
		return errors.New("找不到单据")
	}
	//删除主表信息
	if _, err := to.Delete(badreport); err != nil { //删除主表信息
		to.Rollback()
		return err
	}
	//删除明细信息
	if _, err := to.Raw("DELETE FROM "+models.ErpBadreportDataTableName()+" WHERE badreport_id=?", id).Exec(); err != nil {
		to.Rollback()
		return err
	}
	to.Commit()
	return nil
}

//提交报损单
func (s *BadreportService) SubmitBadreport(depid, badreport_id int64) error {
	if depid == 0 || badreport_id == 0 {
		return errors.New("参数错误")
	}
	badreport, _ := models.GetErpBadreportById(badreport_id)
	if badreport.Id == 0 || badreport.DepartmentId != depid {
		return errors.New("找不到单据信息")
	}
	if badreport.IsTemp == 0 {
		return errors.New("该单据已提交，无需重复")
	}
	badreport_data := make([]*models.ErpBadreportData, 0)
	orm.NewOrm().QueryTable(models.ErpBadreportDataTableName()).Filter("Badreport__Id", badreport_id).Limit(-1).All(&badreport_data)
	if len(badreport_data) <= 0 {
		return errors.New("请选择需要报损的商品")
	}
	for k, _ := range badreport_data {
		badreport.TotalGoodsNum += badreport_data[k].BadreportNum
	}
	badreport.IsTemp = 0
	if _, err := orm.NewOrm().Update(badreport, "TotalGoodsNum", "IsTemp"); err != nil {
		return err
	}
	return nil
}

//报损单审核
func (s *BadreportService) BadreportAuditing(cur *models.BackendUser, badreport_id int64, status_str string) error {
	if cur.DepartmentId == 0 || badreport_id == 0 {
		return errors.New("参数错误")
	}
	var status int
	if status_str == "cennel" {
		status = 2
	}
	if status_str == "yes" {
		status = 1
	}
	if status == 0 {
		return errors.New("状态不正确")
	}
	badreport, _ := models.GetErpBadreportById(badreport_id)
	if badreport.Id == 0 || badreport.DepartmentId != cur.DepartmentId {
		return errors.New("找不到单据信息")
	}
	badreport.Auditing = status
	badreport.AuditingUser = cur.RealName
	badreport.AuditingTime = time.Now().Unix()
	if _, err := orm.NewOrm().Update(badreport, "Auditing", "AuditingUser", "AuditingTime"); err != nil {
		return err
	}
	return nil
}

//执行&驳回单据
func (s *BadreportService) BadreportExecExactly(cur *models.BackendUser, badreport_id int64, status_str string) error {
	if cur.DepartmentId == 0 || badreport_id == 0 {
		return errors.New("参数错误")
	}
	var status int
	if status_str == "cennel" { //驳回
		status = 4
	}
	if status_str == "yes" { //执行
		status = 3
	}
	if status == 0 {
		return errors.New("状态不正确")
	}
	badreport, _ := models.GetErpBadreportById(badreport_id)
	if badreport.Id == 0 || badreport.DepartmentId != cur.DepartmentId {
		return errors.New("找不到单据信息")
	}
	to,_ := orm.NewOrm().Begin()

	if status_str == "yes" { //执行,单独写库
		//获取需要去库存的数据
		badreport_data := make([]*models.ErpBadreportData, 0)
		to.QueryTable(models.ErpBadreportDataTableName()).RelatedSel("Inventory").Filter("Badreport__Id", badreport_id).Limit(-1).All(&badreport_data)
		if len(badreport_data) <= 0 {
			to.Rollback()
			return errors.New("请选择需要报损的商品")
		}
		invSer := new(ErpInventoryService)
		//流水明细
		flowingData := make([]*models.ErpFlowingData, 0)
		for k, _ := range badreport_data {
			value := badreport_data[k]
			inv := value.Inventory
			if value.BadreportNum > inv.Inventory {
				to.Rollback()
				return errors.New("商品库存不足，不允许执行")
			}
			//判断商品是否在盘点中
			if err := StocksCheckIng(inv.Products.Id, cur);err != nil {
				to.Rollback()
				return  err
			}
			primaryStorageNum := inv.Inventory //原库存数据
			if err := invSer.UpdateErpInventory(to, inv, (0 - value.BadreportNum)); err != nil { //更新库存
				to.Rollback()
				return err
			}

			//设置流水明细
			flowing := new(models.ErpFlowingData)
			flowing.Typeid = 4 //退货出库
			flowing.DepartmentId = inv.DepartmentId
			flowing.Products = inv.Products
			flowing.Acceptance = inv.Acceptance
			flowing.Snd = inv.Snd
			flowing.InventoryId = inv.Id
			flowing.PrimaryStorageNum = primaryStorageNum
			flowing.StorageNum = value.BadreportNum
			flowing.PurchaseUpNo = badreport.Number
			flowingData = append(flowingData, flowing)
		}

		//入库记录
		flSer := new(ErpFlowingService)
		//写入流水明细
		if err := flSer.SaveErpFlowingData(to, &models.ErpFlowing{Id: 0}, flowingData); err != nil {
			to.Rollback()
			return err
		}

		//出库结束
	}

	//更新报损主表信息
	badreport.Auditing = status
	badreport.ExecuteUser = cur.RealName
	badreport.ExecuteTime = time.Now().Unix()
	if _, err := to.Update(badreport, "Auditing", "ExecuteUser", "ExecuteTime"); err != nil {
		to.Rollback()
		return err
	}
	to.Commit()
	return nil
}
